Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

doc: broken PerformanceObserver code sample #54227

Merged
merged 1 commit into from
Nov 2, 2024

Conversation

domharrington
Copy link
Contributor

The code sample at the top of the "Performance measurements API" section of the docs does not run.

The code in question:

const { PerformanceObserver, performance } = require('node:perf_hooks');

const obs = new PerformanceObserver((items) => {
  console.log(items.getEntries()[0].duration);
  performance.clearMarks();
});
obs.observe({ type: 'measure' });
performance.measure('Start to Now');

performance.mark('A');
doSomeLongRunningProcess(() => {
  performance.measure('A to Now', 'A');

  performance.mark('B');
  performance.measure('A to B', 'A', 'B');
});

If you replace doSomeLongRunningProcess with an IIFE with a sleep() at the top of it, you get this:

const { PerformanceObserver, performance } = require('node:perf_hooks');

const obs = new PerformanceObserver((items) => {
  console.log(items.getEntries()[0].duration);
  performance.clearMarks();
});
obs.observe({ type: 'measure' });
performance.measure('Start to Now');

performance.mark('A');

(async function doSomeLongRunningProcess() {
  await new Promise(r => setTimeout(r, 5000));
  performance.measure('A to Now', 'A');

  performance.mark('B');
  performance.measure('A to B', 'A', 'B');
})()

When you run this, you get the following output:

$ node performance-test.js
17.873416

node:internal/per_context/domexception:53
    ErrorCaptureStackTrace(this);
    ^
DOMException [SyntaxError]: The "A" performance mark has not been set
    at new DOMException (node:internal/per_context/domexception:53:5)
    at __node_internal_ (node:internal/util:695:10)
    at getMark (node:internal/perf/usertiming:65:11)
    at calculateStartDuration (node:internal/perf/usertiming:202:13)
    at measure (node:internal/perf/usertiming:220:7)
    at Performance.measure (node:internal/perf/performance:135:12)
    at /private/tmp/performance-test.js:14:15

Node.js v20.11.1

I believe it's due to the call to performance.clearMarks(); in the PerformanceObserver callback. If you remove that, it works as expected:

const { PerformanceObserver, performance } = require('node:perf_hooks');

const obs = new PerformanceObserver((items) => {
  console.log(items.getEntries()[0].duration);
});
obs.observe({ type: 'measure' });
performance.measure('Start to Now');

performance.mark('A');

(async function doSomeLongRunningProcess() {
  await new Promise(r => setTimeout(r, 5000));
  performance.measure('A to Now', 'A');

  performance.mark('B');
  performance.measure('A to B', 'A', 'B');
})()
$ node performance-test.js
17.761083
5002.468417

The code sample at the top of the "Performance measurements API"
section of the docs does not run.

The code in question:

```js
const { PerformanceObserver, performance } = require('node:perf_hooks');

const obs = new PerformanceObserver((items) => {
  console.log(items.getEntries()[0].duration);
  performance.clearMarks();
});
obs.observe({ type: 'measure' });
performance.measure('Start to Now');

performance.mark('A');
doSomeLongRunningProcess(() => {
  performance.measure('A to Now', 'A');

  performance.mark('B');
  performance.measure('A to B', 'A', 'B');
});
```

If you replace `doSomeLongRunningProcess` with an IIFE with a sleep()
at the top of it, you get this:

```js
const { PerformanceObserver, performance } = require('node:perf_hooks');

const obs = new PerformanceObserver((items) => {
  console.log(items.getEntries()[0].duration);
  performance.clearMarks();
});
obs.observe({ type: 'measure' });
performance.measure('Start to Now');

performance.mark('A');

(async function doSomeLongRunningProcess() {
  await new Promise(r => setTimeout(r, 5000));
  performance.measure('A to Now', 'A');

  performance.mark('B');
  performance.measure('A to B', 'A', 'B');
})()
```

When you run this, you get the following output:

```sh
$ node performance-test.js
17.873416

node:internal/per_context/domexception:53
    ErrorCaptureStackTrace(this);
    ^
DOMException [SyntaxError]: The "A" performance mark has not been set
    at new DOMException (node:internal/per_context/domexception:53:5)
    at __node_internal_ (node:internal/util:695:10)
    at getMark (node:internal/perf/usertiming:65:11)
    at calculateStartDuration (node:internal/perf/usertiming:202:13)
    at measure (node:internal/perf/usertiming:220:7)
    at Performance.measure (node:internal/perf/performance:135:12)
    at /private/tmp/performance-test.js:14:15

Node.js v20.11.1
```

I believe it's due to the call to `performance.clearMarks();` in the
PerformanceObserver callback. If you remove that, it works as expected:

```js
const { PerformanceObserver, performance } = require('node:perf_hooks');

const obs = new PerformanceObserver((items) => {
  console.log(items.getEntries()[0].duration);
});
obs.observe({ type: 'measure' });
performance.measure('Start to Now');

performance.mark('A');

(async function doSomeLongRunningProcess() {
  await new Promise(r => setTimeout(r, 5000));
  performance.measure('A to Now', 'A');

  performance.mark('B');
  performance.measure('A to B', 'A', 'B');
})()
```

```sh
$ node performance-test.js
17.761083
5002.468417
```
@nodejs-github-bot nodejs-github-bot added doc Issues and PRs related to the documentations. perf_hooks Issues and PRs related to the implementation of the Performance Timing API. labels Aug 6, 2024
@marco-ippolito marco-ippolito added the commit-queue Add this label to land a pull request using GitHub Actions. label Nov 2, 2024
@nodejs-github-bot nodejs-github-bot removed the commit-queue Add this label to land a pull request using GitHub Actions. label Nov 2, 2024
@nodejs-github-bot nodejs-github-bot merged commit e124b0f into nodejs:main Nov 2, 2024
24 checks passed
@nodejs-github-bot
Copy link
Collaborator

Landed in e124b0f

louwers pushed a commit to louwers/node that referenced this pull request Nov 2, 2024
The code sample at the top of the "Performance measurements API"
section of the docs does not run.

The code in question:

```js
const { PerformanceObserver, performance } = require('node:perf_hooks');

const obs = new PerformanceObserver((items) => {
  console.log(items.getEntries()[0].duration);
  performance.clearMarks();
});
obs.observe({ type: 'measure' });
performance.measure('Start to Now');

performance.mark('A');
doSomeLongRunningProcess(() => {
  performance.measure('A to Now', 'A');

  performance.mark('B');
  performance.measure('A to B', 'A', 'B');
});
```

If you replace `doSomeLongRunningProcess` with an IIFE with a sleep()
at the top of it, you get this:

```js
const { PerformanceObserver, performance } = require('node:perf_hooks');

const obs = new PerformanceObserver((items) => {
  console.log(items.getEntries()[0].duration);
  performance.clearMarks();
});
obs.observe({ type: 'measure' });
performance.measure('Start to Now');

performance.mark('A');

(async function doSomeLongRunningProcess() {
  await new Promise(r => setTimeout(r, 5000));
  performance.measure('A to Now', 'A');

  performance.mark('B');
  performance.measure('A to B', 'A', 'B');
})()
```

When you run this, you get the following output:

```sh
$ node performance-test.js
17.873416

node:internal/per_context/domexception:53
    ErrorCaptureStackTrace(this);
    ^
DOMException [SyntaxError]: The "A" performance mark has not been set
    at new DOMException (node:internal/per_context/domexception:53:5)
    at __node_internal_ (node:internal/util:695:10)
    at getMark (node:internal/perf/usertiming:65:11)
    at calculateStartDuration (node:internal/perf/usertiming:202:13)
    at measure (node:internal/perf/usertiming:220:7)
    at Performance.measure (node:internal/perf/performance:135:12)
    at /private/tmp/performance-test.js:14:15

Node.js v20.11.1
```

I believe it's due to the call to `performance.clearMarks();` in the
PerformanceObserver callback. If you remove that, it works as expected:

```js
const { PerformanceObserver, performance } = require('node:perf_hooks');

const obs = new PerformanceObserver((items) => {
  console.log(items.getEntries()[0].duration);
});
obs.observe({ type: 'measure' });
performance.measure('Start to Now');

performance.mark('A');

(async function doSomeLongRunningProcess() {
  await new Promise(r => setTimeout(r, 5000));
  performance.measure('A to Now', 'A');

  performance.mark('B');
  performance.measure('A to B', 'A', 'B');
})()
```

```sh
$ node performance-test.js
17.761083
5002.468417
```

PR-URL: nodejs#54227
Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
aduh95 pushed a commit that referenced this pull request Nov 5, 2024
The code sample at the top of the "Performance measurements API"
section of the docs does not run.

The code in question:

```js
const { PerformanceObserver, performance } = require('node:perf_hooks');

const obs = new PerformanceObserver((items) => {
  console.log(items.getEntries()[0].duration);
  performance.clearMarks();
});
obs.observe({ type: 'measure' });
performance.measure('Start to Now');

performance.mark('A');
doSomeLongRunningProcess(() => {
  performance.measure('A to Now', 'A');

  performance.mark('B');
  performance.measure('A to B', 'A', 'B');
});
```

If you replace `doSomeLongRunningProcess` with an IIFE with a sleep()
at the top of it, you get this:

```js
const { PerformanceObserver, performance } = require('node:perf_hooks');

const obs = new PerformanceObserver((items) => {
  console.log(items.getEntries()[0].duration);
  performance.clearMarks();
});
obs.observe({ type: 'measure' });
performance.measure('Start to Now');

performance.mark('A');

(async function doSomeLongRunningProcess() {
  await new Promise(r => setTimeout(r, 5000));
  performance.measure('A to Now', 'A');

  performance.mark('B');
  performance.measure('A to B', 'A', 'B');
})()
```

When you run this, you get the following output:

```sh
$ node performance-test.js
17.873416

node:internal/per_context/domexception:53
    ErrorCaptureStackTrace(this);
    ^
DOMException [SyntaxError]: The "A" performance mark has not been set
    at new DOMException (node:internal/per_context/domexception:53:5)
    at __node_internal_ (node:internal/util:695:10)
    at getMark (node:internal/perf/usertiming:65:11)
    at calculateStartDuration (node:internal/perf/usertiming:202:13)
    at measure (node:internal/perf/usertiming:220:7)
    at Performance.measure (node:internal/perf/performance:135:12)
    at /private/tmp/performance-test.js:14:15

Node.js v20.11.1
```

I believe it's due to the call to `performance.clearMarks();` in the
PerformanceObserver callback. If you remove that, it works as expected:

```js
const { PerformanceObserver, performance } = require('node:perf_hooks');

const obs = new PerformanceObserver((items) => {
  console.log(items.getEntries()[0].duration);
});
obs.observe({ type: 'measure' });
performance.measure('Start to Now');

performance.mark('A');

(async function doSomeLongRunningProcess() {
  await new Promise(r => setTimeout(r, 5000));
  performance.measure('A to Now', 'A');

  performance.mark('B');
  performance.measure('A to B', 'A', 'B');
})()
```

```sh
$ node performance-test.js
17.761083
5002.468417
```

PR-URL: #54227
Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
doc Issues and PRs related to the documentations. perf_hooks Issues and PRs related to the implementation of the Performance Timing API.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants